package com.byit.interceptor;

import com.alibaba.fastjson.JSON;
import com.byit.EncryptType.MD5;
import com.byit.enums.PromptInfo;
import com.byit.msg.MessageResult;
import com.byit.utils.StringUtil;
import com.byit.utils.TamperUtil;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;


/**
 * 请求签名验证
 * <p>
 * 签名算法: 参数叠加 md5
 *
 * @author marker
 */
public class SignInterceptor implements HandlerInterceptor {
    private Logger logger = LoggerFactory.getLogger(SignInterceptor.class);


    /**
     * 警告信息
     */
    private static String MESSAGE_WARN = JSON.toJSONString(MessageResult.warpper(PromptInfo.ERROR_REQUEST));

    /**
     * 编码
     */
    private static final String encoding = "UTF-8";

    /**
     * 需要排除签名的URL地址列表
     */
    private static final String[] excuseUrls = new String[]{};


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String uri = request.getRequestURI();
        if (uri.contains(".html")||uri.contains(".css")) {
            return true;
        }

        String param = "";
        String secret = "";

        Map<String, String> params = new HashMap<>();
        Enumeration pNames = request.getParameterNames();

        while (pNames.hasMoreElements()) {
            String name = (String) pNames.nextElement();
            String value = request.getParameter(name);
            if (!"secret".equals(name)) {
                params.put(name, value);
            } else {
                secret = value;
            }
        }

        while (pNames.hasMoreElements()) {
            String name = (String) pNames.nextElement();
            String value = request.getParameter(name);
            params.put(name, value);
        }

        if ("POST".equals(request.getMethod())) {
            logger.info("POST请求验证请求参数..........................................");
            //获取header中的timestamp
            String timestamp = request.getHeader("timestamp");
            params.put("timestamp", timestamp);
            param = TamperUtil.sortMapByKeyForString(params);
            logger.info("请求参数：" + param);
            logger.info("加密参数：" + MD5.md5(param) + " 获取的secret:" + secret);
        } else {
            logger.info("GET请求验证请求参数..........................................");
            //GET请求参数header参数
            //APP包名
            String packageName = request.getHeader("packageName");
            //设备唯一编码
            String uid = request.getHeader("uid");

            params.put("packageName", packageName);
            params.put("uid", uid);
            param = TamperUtil.sortMapByKeyForString(params);
            logger.info("请求参数：" + param);
            logger.info("加密参数：" + MD5.md5(param) + " 获取的secret:" + secret);
        }

        /*if (StringUtil.isEmpty(secret) || !secret.equals(MD5.md5(param))) {
            logger.error("加密参数不一致.....................................");
            OutputStream out = response.getOutputStream();
            byte[] bytes = JSON.toJSONString(PromptInfo.ERROR_ILLEGAL_OPERATION).getBytes("UTF-8");
            out.write(bytes);
            out.flush();
            out.close();
            return false;
        }*/

        return true;
    }


    /**
     * 验证需要排除的接口地址。
     *
     * @param uri 请求的URL地址
     * @return
     */
    private boolean validateUrl(String uri) {
        for (String excuseUrl : excuseUrls) {
            if (uri.indexOf(excuseUrl) != -1) {
                return true;
            }
        }
        return false;
    }


    /**
     * 警告信息
     *
     * @param request  请求
     * @param response 响应
     * @throws IOException
     */
    private void warnInfo(HttpServletRequest request, HttpServletResponse response) {
        Writer writer = null;
        try {
            request.setCharacterEncoding(encoding);
            response.setCharacterEncoding(encoding);
            response.setContentType("application/json;charset=UTF-8");
            writer = response.getWriter();
            writer.write(MESSAGE_WARN);
            writer.flush();
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            IOUtils.closeQuietly(writer);
        }

        // 存储非法请求记录

    }

    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
    }

}
